package com.filldream.fastboot.common.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.template.*;
import org.apache.poi.util.IOUtils;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GenUtil {


    public static final String PK = "PRI";

    public static final String DATE = "Date";

    public static final String BIGDECIMAL = "BigDecimal";

    public static final String EXTRA = "auto_increment";

    public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") ;

    /**
     * 数据库字段类型转java字段类型
     * @param type  数据库字段类型
     * @return
     */
    public static String cloToJava(String type){
        Map<String,String> map = new HashMap<>();
        map.put("tinyint","Integer");
        map.put("smallint","Integer");
        map.put("mediumint","Integer");
        map.put("int","Integer");
        map.put("integer","Integer");

        map.put("char","String");
        map.put("varchar","String");
        map.put("tinytext","String");
        map.put("text","String");
        map.put("mediumtext","String");
        map.put("longtext","String");

        map.put("date","Date");
        map.put("datetime","Date");
        map.put("timestamp","Date");

        map.put("bigint","Long");
        map.put("float","Float");
        map.put("double","Double");
        map.put("decimal","BigDecimal");
        map.put("bit","Boolean");

        if( map.containsKey( type ) ){
            return map.get( type );
        }
        return "unknownType";
    }

    public static List<String> getJavaTemps() {
        List<String> templateNames = new ArrayList<>();
        templateNames.add("Entity");
        templateNames.add("AddSTO");
        templateNames.add("ModifySTO");
        templateNames.add("PageSTO");
        templateNames.add("PageDTO");
        templateNames.add("Mapper.xml");
        templateNames.add("Mapper");
        templateNames.add("Service");
        templateNames.add("ServiceImpl");
        templateNames.add("Controller");
        return templateNames;
    }

    public static List<String> getVueTemps() {
        List<String> templateNames = new ArrayList<>();
        templateNames.add("index");
        templateNames.add("index-add-or-update");
        return templateNames;
    }

    public static String getJavaTempsBase(String name) {
        if( name.contains("STO") || name.contains("DTO") || name.contains("Mapper") || name.contains("Entity")){
            return "base";
        }else if( name.contains("Service") ){
            return "core";
        }else if( name.contains("Controller") ){
            return "web";
        }
        return "";
    }

    public static String getJavaFilePath(String templateName, String projectPrefix,String pack, String className, String rootPath) {
        String base = getJavaTempsBase(templateName);

        String projectPath = rootPath + File.separator +  projectPrefix + "-" + base;

        String packagePath = projectPath + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator;
        if (!ObjectUtils.isEmpty(pack)) {
            packagePath += pack.replace(".", File.separator) + File.separator;
        }

        if( templateName.contains("STO") ){
            return packagePath + base + File.separator + "request" + File.separator + "pc" + File.separator + StrUtil.lowerFirst(className)   + File.separator + className + templateName + ".java";
        }

        if( templateName.contains("DTO") ){
            return packagePath + base + File.separator + "response" + File.separator + "pc" + File.separator + StrUtil.lowerFirst(className)   + File.separator + className + templateName + ".java";
        }

        if ("Entity".equals(templateName)) {
            return packagePath + base+ File.separator + "entity" + File.separator + className + ".java";
        }

        if ("Controller".equals(templateName)) {
            return packagePath + base + File.separator + "controller" + File.separator + "pc" + File.separator + "Pc" + className + "Controller.java";
        }

        if ("Service".equals(templateName)) {
            return packagePath + base + File.separator + "service" + File.separator + className + "Service.java";
        }

        if ("ServiceImpl".equals(templateName)) {
            return packagePath + base + File.separator + "service" + File.separator  + "impl"+ File.separator + className + "ServiceImpl.java";
        }


        if ("Mapper".equals(templateName)) {
            return packagePath + base + File.separator + "mapper" + File.separator + className + "Mapper.java";
        }

        if ("Mapper.xml".equals(templateName)) {
            return projectPath + File.separator  + "src" + File.separator + "main"  + File.separator + "resources" + File.separator + "mapper" + File.separator + className + "Mapper.xml";
        }

        return null;
    }

    public static void genFile(File file, Template template, Map<String, Object> map) throws IOException {
        // 生成目标文件
        Writer writer = null;
        try {
            FileUtil.touch(file);
            writer = new FileWriter(file);
            template.render(map, writer);
        } catch (TemplateException | IOException e) {
            throw new RuntimeException(e);
        } finally {
            assert writer != null;
            writer.close();
        }
    }

    public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) {
        response.setCharacterEncoding(request.getCharacterEncoding());
        response.setContentType("application/octet-stream");
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
            IOUtils.copy(fis, response.getOutputStream());
            response.flushBuffer();
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                    if (deleteOnExit) {
                        file.deleteOnExit();
                    }
                } catch (IOException e) {
                    System.out.println(e);
                }
            }
        }
    }


    public static String getVuePath(String templateName, String vuePath,String className, String rootPath) {
        String projectPath = rootPath + File.separator + "views" + File.separator + "modules";
        String[] split = vuePath.split("/");
        for (String item : split) {
            projectPath = projectPath +  File.separator + item;
        }
        if ("index".equals(templateName)) {
            projectPath = projectPath +  File.separator +  StrUtil.lowerFirst(className) + ".vue";
        }
        if ("index-add-or-update".equals(templateName)) {
            projectPath = projectPath +  File.separator +  StrUtil.lowerFirst(className) + "-add-or-update.vue";
        }
        return projectPath;
    }
}
